using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;

namespace GameCore
{
    public class ResourcesManager : MonoBehaviour
    {
        private AssetPackageManager assetPackageManager = new();
        public AssetPackageManager PackageManager => assetPackageManager;

        public virtual async UniTask Init()
        {
            await assetPackageManager.Init();
        }

        public virtual void Update()
        {
            assetPackageManager?.Update(); //转移后=null处理
        }

        public virtual void OnDestroy()
        {
            assetPackageManager?.Dispose();
        }

        /// <summary>
        /// 加载资源，遍历所有资源进行查找尝试加载资源， 如果成功则直接返回
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="assetPath"></param>
        /// <returns></returns>
        public virtual T LoadAsset<T>(string assetPath) where T : Object => assetPackageManager.LoadAsset<T>(assetPath);

        public virtual async UniTask<T> LoadAssetAsync<T>(string assetPath) where T : Object => await assetPackageManager.LoadAssetAsync<T>(assetPath);

        public virtual async UniTask<byte[]> LoadAssetFileAsync(string assetPath, bool isEncrypt = false, bool isAsync = true) => await assetPackageManager.LoadAssetFileAsync(assetPath, isEncrypt, isAsync);

        public virtual T[] LoadAssetWithSubAssets<T>(string assetPath) where T : Object => assetPackageManager.LoadAssetWithSubAssets<T>(assetPath);

        public virtual async UniTask<T[]> LoadAssetWithSubAssetsAsync<T>(string assetPath) where T : Object => await assetPackageManager.LoadAssetWithSubAssetsAsync<T>(assetPath);

        public virtual bool LoadAssetScene(string assetPath, LoadSceneMode mode = LoadSceneMode.Single) => assetPackageManager.LoadAssetScene(assetPath, mode);

        public virtual async UniTask LoadAssetSceneAsync(string assetPath, Action onLoadComplete = null, LoadSceneMode mode = LoadSceneMode.Single)
            => await assetPackageManager.LoadAssetSceneAsync(assetPath, onLoadComplete, mode);

        public virtual async UniTask LoadAssetSceneAsync(string assetPath, LoadSceneMode mode = LoadSceneMode.Single, Action<float> progress = null, Action onLoadComplete = null)
            => await assetPackageManager.LoadAssetSceneAsync(assetPath, mode, progress, onLoadComplete);

        public T Instantiate<T>(string assetPath, Transform parent = null) where T : Object
            => assetPackageManager.Instantiate<T>(assetPath, parent);

        public async UniTask<T> InstantiateAsync<T>(string assetPath, Transform parent = null, bool isAsync = true) where T : Object
            => await assetPackageManager.InstantiateAsync<T>(assetPath, parent, isAsync);

        public T Instantiate<T>(string assetPath, Vector3 position, Quaternion rotation, Transform parent = null) where T : Object
            => assetPackageManager.Instantiate<T>(assetPath, position, rotation, parent);

        public async UniTask<T> InstantiateAsync<T>(string assetPath, Vector3 position, Quaternion rotation, Transform parent = null, bool isAsync = true) where T : Object
            => await assetPackageManager.InstantiateAsync<T>(assetPath, position, rotation, parent, isAsync);

        public void InstantiateAsync<T>(string assetPath, Action<T> onCompleted) where T : Object
            => _ = assetPackageManager.InstantiateAsync(assetPath, onCompleted);

        /// <summary>
        /// 转移对象信息, 保留对象数据, 可能旧的ResourcesManager被销毁, 转移数据给新的ResourcesManager组件
        /// </summary>
        /// <param name="oldResources">旧的资源管理器</param>
        public void Change(ResourcesManager oldResources)
        {
            assetPackageManager = oldResources.assetPackageManager;
            oldResources.assetPackageManager = null;
        }
    }
}